﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿using Microsoft.Win32;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace CooMark
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Image handling properties
        private BitmapImage? loadedImage;
        private double currentScale = 1.0;
        private Point? lastDragPoint;
        private bool isDragging = false;

        // Tool state
        private bool isMeasureToolActive = false;
        private bool isColorPickerActive = false;
        private bool isPanToolActive = false;
        private bool isSpaceKeyPressed = false;
        private string previousToolState = "none"; // Track previous tool for space key toggle
        private Point? measureStartPoint = null;
        private Line? currentMeasureLine = null;
        private TextBlock? currentMeasureText = null;
        private int annotationIdCounter = 0;

        // Collections
        private ObservableCollection<AnnotationItem> annotations = new ObservableCollection<AnnotationItem>();

        public MainWindow()
        {
            InitializeComponent();
            lstAnnotations.ItemsSource = annotations;
            
            // Set initial state
            UpdateStatusBar(null, null);
            
            // Enable keyboard events
            this.KeyDown += MainWindow_KeyDown;
            this.KeyUp += MainWindow_KeyUp;
            this.Focusable = true;
        }

        #region Keyboard Event Handlers

        private void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Space && !isSpaceKeyPressed)
            {
                isSpaceKeyPressed = true;
                
                // Store current tool state
                if (isMeasureToolActive)
                    previousToolState = "measure";
                else if (isColorPickerActive)
                    previousToolState = "colorpicker";
                else if (isPanToolActive)
                    previousToolState = "pan";
                else
                    previousToolState = "none";
                
                // Activate pan tool temporarily
                ActivatePanTool(true);
                e.Handled = true;
            }
            else if (e.Key == Key.V && Keyboard.Modifiers == ModifierKeys.Control)
            {
                // Handle Ctrl+V for paste
                PasteImageFromClipboard();
                e.Handled = true;
            }
        }

        private void PasteImageFromClipboard()
        {
            try
            {
                if (Clipboard.ContainsImage())
                {
                    // Get image from clipboard
                    BitmapSource clipboardImage = Clipboard.GetImage();
                    
                    if (clipboardImage != null)
                    {
                        // Convert BitmapSource to BitmapImage
                        BitmapImage bitmapImage = new BitmapImage();
                        
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            // Encode the BitmapSource to PNG format
                            PngBitmapEncoder encoder = new PngBitmapEncoder();
                            encoder.Frames.Add(BitmapFrame.Create(clipboardImage));
                            encoder.Save(memoryStream);
                            
                            // Create BitmapImage from the encoded data
                            memoryStream.Position = 0;
                            bitmapImage.BeginInit();
                            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                            bitmapImage.StreamSource = memoryStream;
                            bitmapImage.EndInit();
                            bitmapImage.Freeze(); // Make it cross-thread accessible
                        }
                        
                        // Load the pasted image
                        LoadImageFromBitmap(bitmapImage, "Pasted Image");
                    }
                }
                else
                {
                    MessageBox.Show("No image found in clipboard.", "Paste Image", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error pasting image: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void LoadImageFromBitmap(BitmapImage bitmap, string displayName)
        {
            // Set the image
            loadedImage = bitmap;
            mainImage.Source = loadedImage;
            
            // Reset view and clear annotations
            ResetView();
            ClearAllAnnotations();
            
            // Update canvas size to match image
            UpdateCanvasSize();
            
            // Update window title
            Title = $"CooMark - {displayName}";
            
            // Automatically select the hand tool (pan tool) but don't force cursor change
            isPanToolActive = true;
            isMeasureToolActive = false;
            isColorPickerActive = false;
            btnPanTool.IsChecked = true;
            btnMeasureTool.IsChecked = false;
            btnColorPicker.IsChecked = false;
            
            // Only set cursor if mouse is over the image
            if (imageCanvas.IsMouseOver)
                Mouse.OverrideCursor = Cursors.Hand;
            else
                Mouse.OverrideCursor = null;
        }

        private void MainWindow_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Space && isSpaceKeyPressed)
            {
                isSpaceKeyPressed = false;
                
                // Restore previous tool state
                RestorePreviousToolState();
                e.Handled = true;
            }
        }

        private void ActivatePanTool(bool isTemporary = false)
        {
            // Deactivate other tools
            isMeasureToolActive = false;
            isColorPickerActive = false;
            isPanToolActive = true;
            
            if (!isTemporary)
            {
                btnMeasureTool.IsChecked = false;
                btnColorPicker.IsChecked = false;
                btnPanTool.IsChecked = true;
            }
            
            // Only set cursor if mouse is over the image canvas
            if (imageCanvas.IsMouseOver)
                Mouse.OverrideCursor = Cursors.Hand;
        }

        private void RestorePreviousToolState()
        {
            isPanToolActive = false;
            btnPanTool.IsChecked = false;
            
            switch (previousToolState)
            {
                case "measure":
                    isMeasureToolActive = true;
                    btnMeasureTool.IsChecked = true;
                    if (imageCanvas.IsMouseOver)
                        Mouse.OverrideCursor = Cursors.Cross;
                    break;
                case "colorpicker":
                    isColorPickerActive = true;
                    btnColorPicker.IsChecked = true;
                    if (imageCanvas.IsMouseOver)
                        Mouse.OverrideCursor = Cursors.Pen;
                    break;
                case "pan":
                    isPanToolActive = true;
                    btnPanTool.IsChecked = true;
                    if (imageCanvas.IsMouseOver)
                        Mouse.OverrideCursor = Cursors.Hand;
                    break;
                default:
                    Mouse.OverrideCursor = null;
                    break;
            }
        }

        #endregion

        #region Image Loading and Display

        private void btnOpenImage_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = "Image files (*.jpg;*.jpeg;*.png;*.bmp)|*.jpg;*.jpeg;*.png;*.bmp|All files (*.*)|*.*",
                Title = "Select an image"
            };

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    LoadImage(openFileDialog.FileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error loading image: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void btnPasteImage_Click(object sender, RoutedEventArgs e)
        {
            PasteImageFromClipboard();
        }

        private void LoadImage(string filePath)
        {
            // Create a new BitmapImage
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(filePath);
            bitmap.CacheOption = BitmapCacheOption.OnLoad; // Load the image when initialized
            bitmap.EndInit();
            
            // Set the image
            loadedImage = bitmap;
            mainImage.Source = loadedImage;
            
            // Reset view and clear annotations
            ResetView();
            ClearAllAnnotations();
            
            // Update canvas size to match image
            UpdateCanvasSize();
            
            // Update window title with file name
            Title = $"CooMark - {System.IO.Path.GetFileName(filePath)}";
            
            // Automatically select the hand tool (pan tool)
            ActivatePanTool();
        }

        #endregion

        #region Zoom and Pan Functionality

        private void scrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (loadedImage == null) return;

            if (Keyboard.Modifiers == ModifierKeys.Control)
            {
                // Get the position of the mouse relative to the ScrollViewer
                Point mousePos = e.GetPosition(scrollViewer);

                // Calculate zoom factor - smaller increments for smoother zoom
                double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
                
                ApplyZoomAtPoint(zoomFactor, mousePos);
                
                e.Handled = true;
            }
        }

        private void ApplyZoomAtPoint(double zoomFactor, Point mousePos)
        {
            if (loadedImage == null) return;

            // Calculate new scale
            double newScale = currentScale * zoomFactor;
            
            // Limit zoom range
            if (newScale < 0.1) newScale = 0.1;
            if (newScale > 10.0) newScale = 10.0;
            
            if (Math.Abs(newScale - currentScale) < 0.001) return; // No change needed
            
            // Get current scroll position
            double currentHorizontalOffset = scrollViewer.HorizontalOffset;
            double currentVerticalOffset = scrollViewer.VerticalOffset;
            
            // Calculate the point in the content coordinate system
            double contentX = currentHorizontalOffset + mousePos.X;
            double contentY = currentVerticalOffset + mousePos.Y;
            
            // Apply the new scale immediately without animation to avoid position jumping
            currentScale = newScale;
            UpdateCanvasSize();
            
            // Calculate new scroll position to keep the mouse point fixed
            double newContentX = contentX * zoomFactor;
            double newContentY = contentY * zoomFactor;
            
            double newHorizontalOffset = newContentX - mousePos.X;
            double newVerticalOffset = newContentY - mousePos.Y;
            
            // Apply the new scroll position
            scrollViewer.ScrollToHorizontalOffset(Math.Max(0, newHorizontalOffset));
            scrollViewer.ScrollToVerticalOffset(Math.Max(0, newVerticalOffset));
            
            // Update the transform
            ScaleTransform scaleTransform = new ScaleTransform(currentScale, currentScale);
            imageCanvas.RenderTransform = scaleTransform;
            
            // Update status
            UpdateZoomStatus(newScale);
            
            // Update the selected zoom level in the combo box
            UpdateZoomComboBox(newScale);
        }

        private void ApplyZoom(double zoomFactor, Point mousePos)
        {
            // This method is kept for compatibility with other zoom operations
            ApplyZoomAtPoint(zoomFactor, new Point(scrollViewer.ActualWidth / 2, scrollViewer.ActualHeight / 2));
        }

        private void ScaleTransition(double newScale)
        {
            // Create a smooth transition for the scale
            DoubleAnimation scaleAnimation = new DoubleAnimation
            {
                From = currentScale,
                To = newScale,
                Duration = TimeSpan.FromMilliseconds(200)
            };

            // Apply the animation to ScaleTransform
            ScaleTransform scaleTransform = new ScaleTransform(currentScale, currentScale);
            imageCanvas.RenderTransform = scaleTransform;
            
            scaleAnimation.Completed += (s, e) => {
                currentScale = newScale;
                UpdateCanvasSize();
            };
            
            scaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);
        }

        private void UpdateCanvasSize()
        {
            if (loadedImage != null)
            {
                // Update canvas size to match scaled image size
                double scaledWidth = loadedImage.PixelWidth * currentScale;
                double scaledHeight = loadedImage.PixelHeight * currentScale;
                
                imageCanvas.Width = scaledWidth;
                imageCanvas.Height = scaledHeight;
                
                // Also update the image size for proper layout
                mainImage.Width = loadedImage.PixelWidth;
                mainImage.Height = loadedImage.PixelHeight;
            }
        }

        private void UpdateZoomStatus(double scale)
        {
            currentScale = scale;
            txtZoomLevel.Text = $"Zoom: {scale * 100:0}%";
        }

        private void UpdateZoomComboBox(double scale)
        {
            // Find the closest zoom level in the combo box
            double closestDiff = double.MaxValue;
            int closestIndex = 0;
            
            for (int i = 0; i < cmbZoomLevel.Items.Count; i++)
            {
                ComboBoxItem item = (ComboBoxItem)cmbZoomLevel.Items[i];
                double itemScale = Convert.ToDouble(item.Tag);
                double diff = Math.Abs(itemScale - scale);
                
                if (diff < closestDiff)
                {
                    closestDiff = diff;
                    closestIndex = i;
                }
            }
            
            // Only update if the difference is small enough
            if (closestDiff < 0.05)
            {
                cmbZoomLevel.SelectedIndex = closestIndex;
            }
            else
            {
                cmbZoomLevel.SelectedIndex = -1; // Custom zoom level
            }
        }

        private void cmbZoomLevel_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbZoomLevel.SelectedItem == null || loadedImage == null) return;
            
            ComboBoxItem selectedItem = (ComboBoxItem)cmbZoomLevel.SelectedItem;
            double scale = Convert.ToDouble(selectedItem.Tag);
            
            // Apply zoom centered on the image
            Point center = new Point(mainImage.ActualWidth / 2, mainImage.ActualHeight / 2);
            ScaleTransition(scale);
            UpdateZoomStatus(scale);
        }

        private void btnResetView_Click(object sender, RoutedEventArgs e)
        {
            ResetView();
        }

        private void ResetView()
        {
            // Reset zoom level
            currentScale = 1.0;
            ScaleTransition(1.0);
            UpdateZoomStatus(1.0);
            UpdateZoomComboBox(1.0);
            
            // Reset scroll position
            scrollViewer.ScrollToHorizontalOffset(0);
            scrollViewer.ScrollToVerticalOffset(0);
        }

        #endregion

        #region Pan Tool

        private void btnPanTool_Click(object sender, RoutedEventArgs e)
        {
            isPanToolActive = btnPanTool.IsChecked == true;
            isMeasureToolActive = false;
            isColorPickerActive = false;
            btnMeasureTool.IsChecked = false;
            btnColorPicker.IsChecked = false;
            
            // Update cursor
            if (isPanToolActive)
                Mouse.OverrideCursor = Cursors.Hand;
            else
                Mouse.OverrideCursor = null;
        }

        #endregion

        #region Mouse Event Handlers

        private void imageCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (loadedImage == null) return;

            if (isMeasureToolActive && !isSpaceKeyPressed)
            {
                HandleMeasureToolMouseDown(e);
            }
            else if (isColorPickerActive && !isSpaceKeyPressed)
            {
                HandleColorPickerMouseDown(e);
            }
            else if (isPanToolActive || isSpaceKeyPressed || 
                    e.MiddleButton == MouseButtonState.Pressed)
            {
                // Start panning with pan tool, space key, or middle mouse button
                if (e.LeftButton == MouseButtonState.Pressed || e.MiddleButton == MouseButtonState.Pressed)
                {
                    lastDragPoint = e.GetPosition(scrollViewer);
                    isDragging = true;
                    Mouse.OverrideCursor = Cursors.Hand;
                    imageCanvas.CaptureMouse();
                    e.Handled = true;
                }
            }
        }

        private void imageCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (loadedImage == null) return;

            // Update position display
            Point position = e.GetPosition(mainImage);
            UpdateStatusBar(position, null);

            // Update crosshair lines when mouse is over the image
            UpdateCrosshairLines(e.GetPosition(imageCanvas));

            if (isMeasureToolActive && measureStartPoint.HasValue && e.LeftButton == MouseButtonState.Pressed && !isSpaceKeyPressed)
            {
                // Update measurement line while dragging
                UpdateMeasurementLine(e.GetPosition(annotationCanvas));
            }
            else if (isColorPickerActive && !isSpaceKeyPressed)
            {
                // Update color info
                GetPixelColor(position);
            }
            else if (isDragging && lastDragPoint.HasValue)
            {
                // Handle panning
                Point currentPoint = e.GetPosition(scrollViewer);
                Vector delta = lastDragPoint.Value - currentPoint;
                
                scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + delta.X);
                scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + delta.Y);
                
                lastDragPoint = currentPoint;
                
                // Add visual feedback for view boundaries
                UpdateViewBoundaryFeedback();
            }
        }

        private void imageCanvas_MouseEnter(object sender, MouseEventArgs e)
        {
            if (loadedImage != null)
            {
                // Show crosshair lines when mouse enters the image area
                crosshairHorizontal.Visibility = Visibility.Visible;
                crosshairVertical.Visibility = Visibility.Visible;
                
                // Set appropriate cursor based on active tool when mouse enters image area
                if (isPanToolActive || isSpaceKeyPressed)
                    Mouse.OverrideCursor = Cursors.Hand;
                else if (isMeasureToolActive)
                    Mouse.OverrideCursor = Cursors.Cross;
                else if (isColorPickerActive)
                    Mouse.OverrideCursor = Cursors.Pen;
            }
        }

        private void imageCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            // Hide crosshair lines when mouse leaves the image area
            crosshairHorizontal.Visibility = Visibility.Collapsed;
            crosshairVertical.Visibility = Visibility.Collapsed;
            
            // Reset cursor to default when mouse leaves image area
            if (!isDragging) // Don't reset cursor if currently dragging
                Mouse.OverrideCursor = null;
        }

        private void UpdateCrosshairLines(Point mousePosition)
        {
            if (loadedImage == null) return;

            // Update horizontal crosshair line
            crosshairHorizontal.X1 = 0;
            crosshairHorizontal.Y1 = mousePosition.Y;
            crosshairHorizontal.X2 = imageCanvas.ActualWidth;
            crosshairHorizontal.Y2 = mousePosition.Y;

            // Update vertical crosshair line
            crosshairVertical.X1 = mousePosition.X;
            crosshairVertical.Y1 = 0;
            crosshairVertical.X2 = mousePosition.X;
            crosshairVertical.Y2 = imageCanvas.ActualHeight;
        }

        private void imageCanvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (loadedImage == null) return;

            if (isMeasureToolActive && measureStartPoint.HasValue && !isSpaceKeyPressed)
            {
                // Finalize measurement
                FinalizeMeasurement(e.GetPosition(annotationCanvas));
            }
            
            // Reset drag state
            if (isDragging)
            {
                isDragging = false;
                lastDragPoint = null;
                imageCanvas.ReleaseMouseCapture();
                
                // Restore appropriate cursor only if still over the image
                if (imageCanvas.IsMouseOver)
                {
                    if (isPanToolActive || isSpaceKeyPressed)
                        Mouse.OverrideCursor = Cursors.Hand;
                    else if (isMeasureToolActive)
                        Mouse.OverrideCursor = Cursors.Cross;
                    else if (isColorPickerActive)
                        Mouse.OverrideCursor = Cursors.Pen;
                    else
                        Mouse.OverrideCursor = null;
                }
                else
                {
                    // Reset to default cursor if mouse is not over the image
                    Mouse.OverrideCursor = null;
                }
            }
        }

        private void UpdateViewBoundaryFeedback()
        {
            // Add subtle shadow effects at view boundaries to indicate position
            double horizontalRatio = scrollViewer.HorizontalOffset / Math.Max(1, scrollViewer.ScrollableWidth);
            double verticalRatio = scrollViewer.VerticalOffset / Math.Max(1, scrollViewer.ScrollableHeight);
            
            // Update status to show view position
            if (scrollViewer.ScrollableWidth > 0 || scrollViewer.ScrollableHeight > 0)
            {
                txtPosition.Text += $" | View: {horizontalRatio * 100:F0}%, {verticalRatio * 100:F0}%";
            }
        }

        #endregion

        #region Measurement Tool

        private void btnMeasureTool_Click(object sender, RoutedEventArgs e)
        {
            isMeasureToolActive = btnMeasureTool.IsChecked == true;
            isColorPickerActive = false;
            isPanToolActive = false;
            btnColorPicker.IsChecked = false;
            btnPanTool.IsChecked = false;
            
            // Update cursor only if mouse is over the image
            if (isMeasureToolActive && imageCanvas.IsMouseOver)
                Mouse.OverrideCursor = Cursors.Cross;
            else
                Mouse.OverrideCursor = null;
        }

        private void HandleMeasureToolMouseDown(MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                // Get position relative to the annotation canvas
                Point clickPoint = e.GetPosition(annotationCanvas);
                
                if (!measureStartPoint.HasValue)
                {
                    // First point of measurement
                    measureStartPoint = clickPoint;
                    
                    // Create a new line
                    currentMeasureLine = new Line
                    {
                        X1 = clickPoint.X,
                        Y1 = clickPoint.Y,
                        X2 = clickPoint.X,
                        Y2 = clickPoint.Y,
                        Stroke = Brushes.Red,
                        StrokeThickness = 2
                    };
                    
                    // Add line to canvas
                    annotationCanvas.Children.Add(currentMeasureLine);
                    
                    // Create text for measurement
                    currentMeasureText = new TextBlock
                    {
                        Foreground = Brushes.Red,
                        Background = new SolidColorBrush(Color.FromArgb(180, 255, 255, 255)),
                        Padding = new Thickness(2)
                    };
                    
                    annotationCanvas.Children.Add(currentMeasureText);
                }
            }
        }

        private void UpdateMeasurementLine(Point currentPoint)
        {
            if (currentMeasureLine != null && currentMeasureText != null && measureStartPoint.HasValue)
            {
                // Determine if the line should be horizontal or vertical
                // Calculate horizontal and vertical distances
                double horizontalDistance = Math.Abs(currentPoint.X - measureStartPoint.Value.X);
                double verticalDistance = Math.Abs(currentPoint.Y - measureStartPoint.Value.Y);
                
                // Decide whether to make the line horizontal or vertical based on which distance is greater
                bool isHorizontal = horizontalDistance >= verticalDistance;
                
                // Update line end point - constrain to horizontal or vertical only
                if (isHorizontal)
                {
                    // Horizontal line
                    currentMeasureLine.X2 = currentPoint.X;
                    currentMeasureLine.Y2 = measureStartPoint.Value.Y; // Keep Y the same as start point
                    
                    // Calculate distance (horizontal only)
                    double distance = Math.Abs(currentPoint.X - measureStartPoint.Value.X);
                    
                    // Update text
                    currentMeasureText.Text = $"{distance:F1} px";
                    
                    // Position text above the line
                    double midX = (measureStartPoint.Value.X + currentPoint.X) / 2;
                    Canvas.SetLeft(currentMeasureText, midX - currentMeasureText.ActualWidth / 2);
                    Canvas.SetTop(currentMeasureText, measureStartPoint.Value.Y - 20);
                }
                else
                {
                    // Vertical line
                    currentMeasureLine.X2 = measureStartPoint.Value.X; // Keep X the same as start point
                    currentMeasureLine.Y2 = currentPoint.Y;
                    
                    // Calculate distance (vertical only)
                    double distance = Math.Abs(currentPoint.Y - measureStartPoint.Value.Y);
                    
                    // Update text
                    currentMeasureText.Text = $"{distance:F1} px";
                    
                    // Position text to the right of the line
                    Canvas.SetLeft(currentMeasureText, measureStartPoint.Value.X + 5);
                    Canvas.SetTop(currentMeasureText, (measureStartPoint.Value.Y + currentPoint.Y) / 2 - 10);
                }
            }
        }

        private void FinalizeMeasurement(Point endPoint)
        {
            if (currentMeasureLine != null && currentMeasureText != null && measureStartPoint.HasValue)
            {
                // Determine if the line is horizontal or vertical
                double horizontalDistance = Math.Abs(endPoint.X - measureStartPoint.Value.X);
                double verticalDistance = Math.Abs(endPoint.Y - measureStartPoint.Value.Y);
                bool isHorizontal = horizontalDistance >= verticalDistance;
                
                // Constrain the end point to be horizontal or vertical from the start point
                Point constrainedEndPoint;
                double distance;
                
                if (isHorizontal)
                {
                    // Horizontal line
                    constrainedEndPoint = new Point(endPoint.X, measureStartPoint.Value.Y);
                    distance = horizontalDistance;
                }
                else
                {
                    // Vertical line
                    constrainedEndPoint = new Point(measureStartPoint.Value.X, endPoint.Y);
                    distance = verticalDistance;
                }
                
                // Ensure the line reflects the constrained end point
                currentMeasureLine.X2 = constrainedEndPoint.X;
                currentMeasureLine.Y2 = constrainedEndPoint.Y;
                
                // Create annotation item
                int id = ++annotationIdCounter;
                string displayText = isHorizontal ? 
                    $"Horizontal: {distance:F1} px" : 
                    $"Vertical: {distance:F1} px";
                
                AnnotationItem item = new AnnotationItem
                {
                    Id = id,
                    Type = AnnotationType.Measurement,
                    DisplayText = displayText,
                    Line = currentMeasureLine,
                    TextBlock = currentMeasureText,
                    StartPoint = measureStartPoint.Value,
                    EndPoint = constrainedEndPoint
                };
                
                // Add to collection
                annotations.Add(item);
                
                // Reset for next measurement
                measureStartPoint = null;
                currentMeasureLine = null;
                currentMeasureText = null;
            }
        }

        private double CalculateDistance(double x1, double y1, double x2, double y2)
        {
            return Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
        }

        #endregion

        #region Color Picker

        private void btnColorPicker_Click(object sender, RoutedEventArgs e)
        {
            isColorPickerActive = btnColorPicker.IsChecked == true;
            isMeasureToolActive = false;
            isPanToolActive = false;
            btnMeasureTool.IsChecked = false;
            btnPanTool.IsChecked = false;
            
            // Update cursor only if mouse is over the image
            if (isColorPickerActive && imageCanvas.IsMouseOver)
                Mouse.OverrideCursor = Cursors.Pen;
            else
                Mouse.OverrideCursor = null;
        }

        private void HandleColorPickerMouseDown(MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Point position = e.GetPosition(mainImage);
                Color? pixelColor = GetPixelColor(position);
                
                if (pixelColor.HasValue)
                {
                    // Create a color sample rectangle
                    Rectangle colorSample = new Rectangle
                    {
                        Width = 10,
                        Height = 10,
                        Fill = new SolidColorBrush(pixelColor.Value),
                        Stroke = Brushes.Black,
                        StrokeThickness = 1
                    };
                    
                    // Create text for color info - only showing hex value
                    TextBlock colorText = new TextBlock
                    {
                        Text = $"#{pixelColor.Value.R:X2}{pixelColor.Value.G:X2}{pixelColor.Value.B:X2}",
                        Foreground = Brushes.Black,
                        Background = new SolidColorBrush(Color.FromArgb(180, 255, 255, 255)),
                        Padding = new Thickness(2)
                    };
                    
                    // Position elements
                    Canvas.SetLeft(colorSample, position.X + 5);
                    Canvas.SetTop(colorSample, position.Y + 5);
                    
                    Canvas.SetLeft(colorText, position.X + 20);
                    Canvas.SetTop(colorText, position.Y + 5);
                    
                    // Add to canvas
                    annotationCanvas.Children.Add(colorSample);
                    annotationCanvas.Children.Add(colorText);
                    
                    // Create annotation item
                    int id = ++annotationIdCounter;
                    string displayText = $"Color: #{pixelColor.Value.R:X2}{pixelColor.Value.G:X2}{pixelColor.Value.B:X2}";
                    
                    AnnotationItem item = new AnnotationItem
                    {
                        Id = id,
                        Type = AnnotationType.ColorPicker,
                        DisplayText = displayText,
                        ColorSample = colorSample,
                        TextBlock = colorText,
                        Position = position,
                        Color = pixelColor.Value
                    };
                    
                    // Add to collection
                    annotations.Add(item);
                }
            }
        }

        private Color? GetPixelColor(Point position)
        {
            if (loadedImage == null || 
                position.X < 0 || position.Y < 0 || 
                position.X >= loadedImage.PixelWidth || position.Y >= loadedImage.PixelHeight)
            {
                return null;
            }
            
            try
            {
                // Create a RenderTargetBitmap to safely get pixel data
                RenderTargetBitmap renderBitmap = new RenderTargetBitmap(
                    loadedImage.PixelWidth,
                    loadedImage.PixelHeight,
                    96, 96,
                    PixelFormats.Pbgra32);
                
                // Create a DrawingVisual to draw the image
                DrawingVisual drawingVisual = new DrawingVisual();
                using (DrawingContext drawingContext = drawingVisual.RenderOpen())
                {
                    drawingContext.DrawImage(loadedImage, new Rect(0, 0, loadedImage.PixelWidth, loadedImage.PixelHeight));
                }
                
                // Render the image to the bitmap
                renderBitmap.Render(drawingVisual);
                
                // Create a cropped bitmap for just the pixel we want
                CroppedBitmap croppedBitmap = new CroppedBitmap(
                    renderBitmap,
                    new Int32Rect((int)position.X, (int)position.Y, 1, 1));
                
                // Create a byte array to hold the pixel data
                byte[] pixels = new byte[4];
                croppedBitmap.CopyPixels(pixels, 4, 0);
                
                // Create color from BGRA values
                Color color = Color.FromArgb(pixels[3], pixels[0], pixels[1], pixels[2]);
                
                // Update status bar
                UpdateStatusBar(position, color);
                
                return color;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error getting pixel color: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return null;
            }
        }

        #endregion

        #region Annotation Management

        private void btnClearAnnotations_Click(object sender, RoutedEventArgs e)
        {
            ClearAllAnnotations();
        }

        private void ClearAllAnnotations()
        {
            // Clear canvas
            annotationCanvas.Children.Clear();
            
            // Clear collection
            annotations.Clear();
            
            // Reset counter
            annotationIdCounter = 0;
            
            // Reset measurement state
            measureStartPoint = null;
            currentMeasureLine = null;
            currentMeasureText = null;
        }

        private void btnDeleteAnnotation_Click(object sender, RoutedEventArgs e)
        {
            if (sender is Button button && button.Tag is int id)
            {
                DeleteAnnotation(id);
            }
        }

        private void DeleteAnnotation(int id)
        {
            // Find annotation
            AnnotationItem? itemToRemove = null;
            
            foreach (var item in annotations)
            {
                if (item.Id == id)
                {
                    itemToRemove = item;
                    break;
                }
            }
            
            if (itemToRemove != null)
            {
                // Remove visual elements
                if (itemToRemove.Line != null)
                    annotationCanvas.Children.Remove(itemToRemove.Line);
                
                if (itemToRemove.TextBlock != null)
                    annotationCanvas.Children.Remove(itemToRemove.TextBlock);
                
                if (itemToRemove.ColorSample != null)
                    annotationCanvas.Children.Remove(itemToRemove.ColorSample);
                
                // Remove from collection
                annotations.Remove(itemToRemove);
            }
        }

        private void lstAnnotations_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lstAnnotations.SelectedItem is AnnotationItem selectedItem)
            {
                // Highlight the selected annotation
                if (selectedItem.Type == AnnotationType.Measurement && selectedItem.Line != null)
                {
                    // Temporarily increase line thickness
                    selectedItem.Line.StrokeThickness = 4;
                    
                    // Reset after a delay
                    System.Threading.Tasks.Task.Delay(1000).ContinueWith(_ =>
                    {
                        Dispatcher.Invoke(() =>
                        {
                            selectedItem.Line.StrokeThickness = 2;
                        });
                    });
                }
            }
        }

        #endregion

        #region Status Bar Updates

        private void UpdateStatusBar(Point? position, Color? color)
        {
            // Update position text
            if (position.HasValue && loadedImage != null)
            {
                int x = (int)position.Value.X;
                int y = (int)position.Value.Y;
                
                if (x >= 0 && y >= 0 && x < loadedImage.PixelWidth && y < loadedImage.PixelHeight)
                {
                    txtPosition.Text = $"Position: X={x}, Y={y}";
                }
                else
                {
                    txtPosition.Text = "Position: --";
                }
            }
            else
            {
                txtPosition.Text = "Position: --";
            }
            
            // Update color text - only showing hex value
            if (color.HasValue)
            {
                Color c = color.Value;
                txtColorInfo.Text = $"Color: #{c.R:X2}{c.G:X2}{c.B:X2}";
            }
            else
            {
                txtColorInfo.Text = "Color: --";
            }
        }

        #endregion
    }

    #region Supporting Classes

    public enum AnnotationType
    {
        Measurement,
        ColorPicker
    }

    public class AnnotationItem
    {
        public int Id { get; set; }
        public AnnotationType Type { get; set; }
        public string DisplayText { get; set; } = "";
        
        // Measurement properties
        public Line? Line { get; set; }
        public Point StartPoint { get; set; }
        public Point EndPoint { get; set; }
        
        // Color picker properties
        public Rectangle? ColorSample { get; set; }
        public Point Position { get; set; }
        public Color Color { get; set; }
        
        // Common properties
        public TextBlock? TextBlock { get; set; }
    }

    #endregion
}